#include <windows.h>
#include <XAudio2.h>
#pragma comment(lib,"xaudio2.lib") 

/*
#include"SpeechSynthesis.h"这是SpeechSynthesis的头文件
*/
SpeechSynthesis syth(SC_Mandarin);                              // 语音合成器-简体中文转普通话
WAVEFORMATEX format = syth.wfx;                                 // 波形格式

IXAudio2 * XAudioEngine = NULL;                                 // IXAduio2音频引擎
IXAudio2MasteringVoice * pmaster = NULL;                        // 声音管理器
IXAudio2SourceVoice * pSource = NULL;                           // 音源
XAUDIO2_BUFFER sBuffer = {};                                    // 音源缓冲区
XAUDIO2_VOICE_STATE pState = {};                                // 缓冲区状态

// 单独列出初始化和卸载，可以加入到你的构造-析构函数中
BOOL Init()
{
    // XAudio2初始化
    CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (FAILED(XAudio2Create(&XAudioEngine)))return FALSE;
    if (FAILED(XAudioEngine->CreateMasteringVoice(&pmaster)))return FALSE;
    if (FAILED(XAudioEngine->CreateSourceVoice(&pSource, &format)))return FALSE;
    return TRUE;
}

void Uninit()
{
    XAudioEngine->Release();
    CoUninitialize();
}
// 语音合成与音频呈现的函数
BOOL Vocalize(wchar_t * srcSentence)
{
    pSource->Start();                                               // 开启音源
    sBuffer.pAudioData = syth.Synthesize(srcSentence);              // 合成音频
    sBuffer.AudioBytes = syth.pcm_data.size();                      // 一次性载入音频缓冲区
    if (FAILED(pSource->SubmitSourceBuffer(&sBuffer)))return 0;     // 装载音频
    // 等待播放完毕或者打断
    for (pSource->GetState(&pState); pState.BuffersQueued; pSource->GetState(&pState))
        Sleep(1);
    pSource->Stop();                                                // 关闭音源
    pSource->FlushSourceBuffers();                                  // 缓冲区清空(可选)
    return TRUE;
}

int main(int argc, char *argv[])
{
    Init();
    Vocalize(L"这是一段测试语音");
    Vocalize(L"节选于《让我在你的心里自由自在》");
    Vocalize(L"她瞬间就摘下了自己平静的面具，阳光般的笑容撒满她的眼睛。她向我投来真实的目光，她的声音让我无所适从地被打动。她时而安静、柔顺得像个邻家女孩，时而一双又黑又大的眼睛闪烁出精灵的光芒。在她的音乐里，她就是一只在草原蔚蓝澄明的天际自由翱翔的苍鹰，释放着自己宽阔的憧憬与广袤的理想。她的内心孤独而迷茫，踯躅而忧郁，但依然顽固地看守着精神的自由，也学会了在现实生活中默默承受。");
    Uninit();
    return 0;
}